//---------------------------------------------------------------------------

#include "vcl_stl.h"
#pragma hdrstop

#include "h_base.h"
#include "h_xml.h"
#include "h_global.h"
using namespace h_base;
using namespace h_xml;

#include "t_mainform.h"
#include "h_stage.h"
#include "h_g.h"
#include "h_stageicon.h"
#include "h_designcontrol.h"
#include "h_server.h"
#include "t_batform.h"

//---------------------------------------------------------------------------

__fastcall HDesignControl::HDesignControl(
   Classes::TComponent* AOwner) : TScrollingWinControl(AOwner)
{
   Canvas = new TControlCanvas;
   Canvas->Control = this;
   DoubleBuffered = true;

   TabStop = true;
   AutoScroll = true;
}

__fastcall HDesignControl::~HDesignControl(void)
{
   for( map<UTF8String, HStage*>::iterator Iter = ControlMap.begin();
        Iter != ControlMap.end(); ++Iter )
      delete Iter->second;

   delete Canvas;
}

bool __fastcall HDesignControl::GroupExist(const UTF8String &Name)
{
   for( map<UTF8String, HStage*>::iterator Iter = ControlMap.begin();
        Iter != ControlMap.end(); ++Iter )
   {
      HStage *Stage = Iter->second;
      if ( Stage->GetType() != "GROUP" )
      {
         continue;
      }
      HStageGroup::HInfo Info;
      HStageGroup *Group = (HStageGroup*)Stage;
      Group->GetInfo(Info);
      if ( Info.Group == Name )
      {
         return true;
      }
   }

   return false;
}

HStage * __fastcall HDesignControl::FindControlByName(const UTF8String &Name)
{
   if ( ControlMap.find(Name) == ControlMap.end() )
   {
      return NULL;
   }

   return ControlMap[Name];
}

void __fastcall HDesignControl::WndProc(TMessage &Message)
{
   if( Message.Msg >= WM_MOUSEFIRST &&
       Message.Msg <= WM_MOUSELAST &&
       Message.Msg != WM_MOUSEWHEEL )
   {
      TControl::WndProc(Message);
      return;
   }

   if ( Message.Msg == WM_MOUSEWHEEL )
   {
      int i = (signed short)(Message.WParam >> 16);
      int OldPos = VertScrollBar->Position;
      VertScrollBar->Position -= i;
      if ( VertScrollBar->Position != OldPos )
      {
         Invalidate();
      }
   }

   if ( Message.Msg == WM_HSCROLL ||
        Message.Msg == WM_VSCROLL )
   {
      Invalidate();
   }

   inherited::WndProc(Message);
}

void __fastcall HDesignControl::WMPaint(TWMPaint &Message)
{
   HDC DC;
   TPaintStruct PS;
   int BgWidth = MainForm->InitWidth - ( MainForm->Width - Width );
   int BgHeight = MainForm->InitHeight - ( MainForm->Height - Height );

   if( Message.DC == 0)
      DC = BeginPaint(Handle, &PS);
   else
      DC = Message.DC;

   Canvas->Lock();
   Canvas->Handle = DC;

   Canvas->Brush->Color = h_g::Background->Canvas->Pixels[0][0];
   Canvas->FillRect(Canvas->ClipRect);
   Canvas->Draw(BgWidth - h_g::Background->Width
//      - HorzScrollBar->Position
      ,
      BgHeight - h_g::Background->Height
//      - VertScrollBar->Position
      ,
      h_g::Background);

   if ( h_g::CustLogoFlag && h_g::CustLogo != NULL )
   {
      Canvas->Draw(BgWidth - h_g::CustLogo->Width
//         - HorzScrollBar->Position
         ,
         BgHeight - h_g::CustLogo->Height
//         - VertScrollBar->Position
         ,
         h_g::CustLogo);
   }

   TMainForm::HInfo Info;

   MainForm->GetInfo(Info);

   if ( Info.Banner != "" )
   {
      TFont *FontBak = new TFont();
      FontBak->Assign(Canvas->Font);
      Canvas->Font->Name = Info.BannerFontName;
      Canvas->Font->Size = Info.BannerFontSize;
      Set<TFontStyle, fsBold, fsStrikeOut> FontStyle;
      IntToFontStyle(Info.BannerFontStyle, FontStyle);
      Canvas->Font->Style = FontStyle;
      Canvas->Font->Charset = 1;
      Canvas->Font->Color = h_g::TextColor;
      Canvas->Brush->Style = bsClear; 
      int TextWidth = Canvas->TextWidth(Info.Banner);
      int TextHeight = Canvas->TextHeight(Info.Banner);
      const int Margin = 10;
      switch ( Info.BannerPosition )
      {
      case 0 : // Top left corner
         Canvas->TextOut(Margin - HorzScrollBar->Position,
            Margin - VertScrollBar->Position, Info.Banner);
         break;
      case 1 : // Top right corner
         Canvas->TextOut(BgWidth - TextWidth - Margin - HorzScrollBar->Position,
            Margin - VertScrollBar->Position, Info.Banner);
         break;
      case 2 : // Bottom left corner
         Canvas->TextOut(Margin - HorzScrollBar->Position,
            BgHeight - TextHeight - Margin - VertScrollBar->Position,
            Info.Banner);
         break;
      case 3 : // Bottom right corner
         Canvas->TextOut(BgWidth - TextWidth - Margin - HorzScrollBar->Position,
            BgHeight - TextHeight - Margin - VertScrollBar->Position,
            Info.Banner);
         break;
      case 4 : // Top middle
         Canvas->TextOut(( BgWidth - TextWidth ) / 2 - HorzScrollBar->Position,
            Margin - VertScrollBar->Position, Info.Banner);
         break;
      case 5 : // Bottom middle
         Canvas->TextOut(( BgWidth - TextWidth ) / 2 - HorzScrollBar->Position,
            BgHeight - TextHeight - Margin - VertScrollBar->Position,
            Info.Banner);
         break;
      }
      Canvas->Font->Assign(FontBak);
      delete FontBak;
   }

   for( map<UTF8String, HLinkInfo>::iterator Iter = LinkMap.begin();
       Iter != LinkMap.end(); ++Iter )
      DrawLink(Iter->first, true);

   for( map<UTF8String, HLinkInfo>::iterator Iter = LinkMap.begin();
       Iter != LinkMap.end(); ++Iter )
      DrawLink(Iter->first, false);

   if ( ControlMap.find(FocusedJobName) != ControlMap.end() )
   {
      HStageIcon *Icon = ControlMap[FocusedJobName]->GetIcon();
      Canvas->Brush->Color = clRed;
      Canvas->FrameRect(TRect(Icon->Left - 3, Icon->Top - 3,
         Icon->Left + Icon->Width + 3,
         Icon->Top + Icon->Height + 3));
      Canvas->FrameRect(TRect(Icon->Left - 2, Icon->Top - 2,
         Icon->Left + Icon->Width + 2,
         Icon->Top + Icon->Height + 2));
      Canvas->FrameRect(TRect(Icon->Left - 1, Icon->Top - 1,
         Icon->Left + Icon->Width + 1,
         Icon->Top + Icon->Height + 1));
   }

   Canvas->Handle = 0;
   Canvas->Unlock();

   PaintControls(DC, NULL);
   
   if( Message.DC == 0 )
      EndPaint(Handle, &PS);
}

void __fastcall HDesignControl::SetFocusedJob(const UTF8String &Name,
   bool ScrollToCenter)
{
   UTF8String NewName = Name;

   if ( ControlMap.find(NewName) == ControlMap.end() )
   {
      NewName = "";
   }
   else if ( ScrollToCenter )
   {
      HStageIcon *Icon = ControlMap[NewName]->GetIcon();
      int DeltaX = ClientWidth / 2 - ( Icon->Left + Icon->Width / 2 );
      int DeltaY = ClientHeight / 2 - ( Icon->Top + Icon->Height / 2 );
      int PosX = HorzScrollBar->Position;
      int PosY = VertScrollBar->Position;
      PosX -= DeltaX;
      PosY -= DeltaY;
      HorzScrollBar->Position = PosX;
      VertScrollBar->Position = PosY;
   }

   if ( FocusedJobName != NewName )
   {
      if ( FocusedJobName != "" )
      {
         HStageIcon *Icon = ControlMap[FocusedJobName]->GetIcon();
         TRect Rect1(Icon->Left - 3, Icon->Top - 3,
            Icon->Left + Icon->Width + 3,
            Icon->Top);
         InvalidateRect(Handle, &Rect1, false);
         TRect Rect2(Icon->Left - 3, Icon->Top + Icon->Height,
            Icon->Left + Icon->Width + 3,
            Icon->Top + Icon->Height + 3);
         InvalidateRect(Handle, &Rect2, false);
         TRect Rect3(Icon->Left - 3, Icon->Top - 3,
            Icon->Left,
            Icon->Top + Icon->Height + 3);
         InvalidateRect(Handle, &Rect3, false);
         TRect Rect4(Icon->Left + Icon->Width, Icon->Top - 3,
            Icon->Left + Icon->Width + 3,
            Icon->Top + Icon->Height + 3);
         InvalidateRect(Handle, &Rect4, false);
      }
      FocusedJobName = NewName;
      if ( FocusedJobName != "" )
      {
         HStageIcon *Icon = ControlMap[FocusedJobName]->GetIcon();
         TRect Rect1(Icon->Left - 3, Icon->Top - 3,
            Icon->Left + Icon->Width + 3,
            Icon->Top);
         InvalidateRect(Handle, &Rect1, false);
         TRect Rect2(Icon->Left - 3, Icon->Top + Icon->Height,
            Icon->Left + Icon->Width + 3,
            Icon->Top + Icon->Height + 3);
         InvalidateRect(Handle, &Rect2, false);
         TRect Rect3(Icon->Left - 3, Icon->Top - 3,
            Icon->Left,
            Icon->Top + Icon->Height + 3);
         InvalidateRect(Handle, &Rect3, false);
         TRect Rect4(Icon->Left + Icon->Width, Icon->Top - 3,
            Icon->Left + Icon->Width + 3,
            Icon->Top + Icon->Height + 3);
         InvalidateRect(Handle, &Rect4, false);
      }
      Update();
   }
   else
   {
      FocusedJobName = NewName;
   }
}

void __fastcall HDesignControl::WMLButtonDown(TWMLButtonDown &Message)
{
   UTF8String Name;

   Name = FindControlByPos(Message.XPos, Message.YPos);
   SetFocusedJob(Name);
   SetFocus();
}

void __fastcall HDesignControl::WMLButtonDblClk(TWMLButtonDblClk &Message)
{
   UTF8String Name;

   Name = FindControlByPos(Message.XPos, Message.YPos);

   HServer::LockRefresh();

   if( Name == "" )
      BatForm->Edit();
   else
      ControlMap[Name]->EditProperty();

   HServer::UnlockRefresh();
}

void __fastcall HDesignControl::WMRButtonUp(TWMRButtonUp &Message)
{
   UTF8String Name;

   Name = FindControlByPos(Message.XPos, Message.YPos);

   if( Name == "" )
      return;

   UTF8String Type = ControlMap[Name]->GetType();

   if( Type == "CONNECTOR" )
      return;
      
   SetFocusedJob(Name);
   MainForm->SelectedStage = ControlMap[Name];
   inherited::Dispatch(&Message);
}

//---------------------------------------------------------------------------

void __fastcall HDesignControl::DrawLink(const UTF8String &Name,
   bool First)
{
   int Type;
   vector<TPoint> Points;
   vector<TPoint> Points2;
   int ArrowWidth = h_g::BitmapArrow[0]->Width;
   int ArrowLength = h_g::BitmapArrow[0]->Height;

   GetLinkPoints(Name, Points, Type);

   for ( int i = 0; i < Points.size(); i++ )
   {
      Points2.push_back(TPoint(Points[i].x + 1, Points[i].y + 1));
   }

   if ( First )
   {
      Canvas->Pen->Color = h_g::LineShadowColor;
      Canvas->Polyline(&Points2[0], Points2.size() - 1);
   }
   else
   {
      Canvas->Pen->Color = h_g::LineColor;
      Canvas->Polyline(&Points[0], Points.size() - 1);
   }

   TPoint End = Points.back();
   Points.clear();

   if ( First && Type != 4 )
   {
      switch( Type )
      {
      case 0 :
         Canvas->Draw(End.x - 1, End.y - ArrowWidth / 2,
            h_g::BitmapArrow[h_g::adRight]);
         break;
      case 1 :
         Canvas->Draw(End.x - ArrowLength + 1 + 1, End.y - ArrowWidth / 2,
            h_g::BitmapArrow[h_g::adLeft]);
         break;
      case 2 :
         Canvas->Draw(End.x - ArrowWidth / 2, End.y - 1,
            h_g::BitmapArrow[h_g::adDown]);
         break;
      case 3 :
         Canvas->Draw(End.x - ArrowWidth / 2, End.y - ArrowLength + 1 + 1,
            h_g::BitmapArrow[h_g::adUp]);
         break;
      }
   }

   return;
}

void __fastcall HDesignControl::GetLinkPoints(const UTF8String &Name,
   vector<TPoint> &Points, int &Type)
{
   int ArrowLength = h_g::BitmapArrow[0]->Height;

   bool HorzFlag, VertFlag;
   int HorzType, VertType;
   TPoint HorzStartPoint, HorzEndPoint;
   TPoint VertStartPoint, VertEndPoint;
   TRect BeginRect, EndRect;
   TPoint Start, End;
   bool HideArrow = false;
   HStage *Stage;
   int BeginLabelDelta = 0;
   int EndLabelDelta = 0;
   TLabel *Label;

   Stage = ControlMap[LinkMap[Name].StartControl];
   BeginRect = Stage->GetIcon()->BoundsRect;
   Label = Stage->GetLabel();

   if ( Label != NULL )
   {
      BeginLabelDelta = Label->Height + 8;
   }

   Stage = ControlMap[LinkMap[Name].EndControl];
   EndRect = Stage->GetIcon()->BoundsRect;
   Label = Stage->GetLabel();

   if ( Label != NULL )
   {
      EndLabelDelta = Label->Height + 8;
   }

   if ( Stage->GetType() == "CONNECTOR" )
   {
      HStageConnector *Connector = (HStageConnector*)Stage;
      HStageConnector::HInfo Info;
      Connector->GetInfo(Info);
      HideArrow = Info.HideArrow;
   }

   if( BeginRect.Right < EndRect.Left )
   {
      HorzFlag = true;
      HorzStartPoint.x = BeginRect.Right;
      HorzStartPoint.y = ( BeginRect.Top + BeginRect.Bottom - 1 ) / 2;
      HorzEndPoint.x = EndRect.Left;
      HorzEndPoint.y = ( EndRect.Top + EndRect.Bottom - 1 ) / 2;
      HorzType = 0;
   }
   else if( BeginRect.Left > EndRect.Right )
   {
      HorzFlag = true;
      HorzStartPoint.x = BeginRect.Left;
      HorzStartPoint.y = ( BeginRect.Top + BeginRect.Bottom - 1 ) / 2;
      HorzEndPoint.x = EndRect.Right;
      HorzEndPoint.y = ( EndRect.Top + EndRect.Bottom - 1 ) / 2;
      HorzType = 1;
   }
   else
      HorzFlag = false;

   if( BeginRect.Bottom + BeginLabelDelta < EndRect.Top )
   {
      VertFlag = true;
      VertStartPoint.x = ( BeginRect.Left + BeginRect.Right - 1 ) / 2;
      VertStartPoint.y = BeginRect.Bottom + BeginLabelDelta;
      VertEndPoint.x = ( EndRect.Left + EndRect.Right - 1 ) / 2;
      VertEndPoint.y = EndRect.Top;
      VertType = 2;
   }
   else if( BeginRect.Top > EndRect.Bottom + EndLabelDelta )
   {
      VertFlag = true;
      VertStartPoint.x = ( BeginRect.Left + BeginRect.Right - 1 ) / 2;
      VertStartPoint.y = BeginRect.Top;
      VertEndPoint.x = ( EndRect.Left + EndRect.Right - 1 ) / 2;
      VertEndPoint.y = EndRect.Bottom + EndLabelDelta;
      VertType = 3;
   }
   else
      VertFlag = false;

   if( VertFlag )
   {
      Start = VertStartPoint;
      End = VertEndPoint;
      Type = VertType;
   }
   else if( HorzFlag )
   {
      Start = HorzStartPoint;
      End = HorzEndPoint;
      Type = HorzType;
   }
   else
   {
      Start.x = ( BeginRect.Left + BeginRect.Right - 2 ) / 2;
      Start.y = BeginRect.Top;
      End.x = ( EndRect.Left + EndRect.Right - 2 ) / 2;
      End.y = EndRect.Top;
      Type = 2;
   }

   int DeltaX;
   int DeltaY;
   TPoint Point;

   Points.clear();

   if ( Type == 0 || Type == 1 )
   {
      if ( Type == 0 && !HideArrow )            // Right
      {
         End.x -= ArrowLength;
      }
      if ( Type == 1 && !HideArrow )            // Left
      {
         End.x += ArrowLength;
      }
      DeltaX = End.x - Start.x;
      DeltaY = End.y - Start.y;
      if ( DeltaY == 0 )
      {
         Points.push_back(Start);
         Points.push_back(End);
      }
      else
      {
         Points.push_back(Start);
         Point.x = ( Start.x + End.x - 2 ) / 2;
         Point.y = Start.y;
         Points.push_back(Point);
         Point.x = ( Start.x + End.x - 2 ) / 2;
         Point.y = End.y;
         Points.push_back(Point);
         Points.push_back(End);
      }
   }
   else
   {
      if ( Type == 2 && !HideArrow )            // Down
      {
         End.y -= ArrowLength;
      }
      if ( Type == 3 && !HideArrow )            // Up
      {
         End.y += ArrowLength;
      }
      DeltaX = End.x - Start.x;
      DeltaY = End.y - Start.y;
      if ( DeltaX == 0 )
      {
         Points.push_back(Start);
         Points.push_back(End);
      }
      else
      {
         Points.push_back(Start);
         Point.x = Start.x;
         Point.y = ( Start.y + End.y - 2 ) / 2;
         Points.push_back(Point);
         Point.x = End.x;
         Point.y = ( Start.y + End.y - 2 ) / 2;
         Points.push_back(Point);
         Points.push_back(End);
      }
   }

   if ( HideArrow )
   {
      Type = 4;
   }
}

UTF8String __fastcall HDesignControl::FindControlByPos(int x, int y)
{
   HStageIcon *Control;
   map<UTF8String, HStage*>::iterator Iter;

   for( Iter = ControlMap.begin(); Iter != ControlMap.end(); ++Iter )
   {
      Control = Iter->second->GetIcon();
      if( x >= Control->Left &&
          x < Control->Left + Control->Width &&
          y >= Control->Top &&
          y < Control->Top + Control->Height )
         return Iter->first;
   }

   return "";
}

UTF8String __fastcall HDesignControl::NewLinkName(void)
{
   int i;
   UTF8String Name;
   UTF8String Prefix = "LINK_";

   for( i = 1; ; i++ )
   {
      Name = Prefix + UTF8String(i);
      if( !LinkExist(Name) )
         return Name;
   }
}

bool __fastcall HDesignControl::LinkExist(const UTF8String &Name)
{
   return LinkMap.find(Name) != LinkMap.end();
}

void __fastcall HDesignControl::LoadFromXmlTree(const UTF8String &GroupId,
   HXmlTree *XmlTree, bool XmlPropertyFlag)
{
   set<UTF8String> JobSet;
   vector<HXmlTree*> Nodes;

   XmlTree->GetChildren("JOB", Nodes);

   for( int i = 0; i < Nodes.size(); i++ )
   {
      UTF8String Name;
      UTF8String TmpStr;
      HStage *Stage;
      int x, y;

      if ( XmlPropertyFlag )
      {
         Name = Nodes[i]->GetPropertyUpper("NAME").c_str();
      }
      else
      {
         Name = Nodes[i]->GetValueUpper("NAME").c_str();
      }

      if ( JobSet.find(Name) == JobSet.end() )
      {
         JobSet.insert(Name);
      }
      else
      {
         continue;
      }
      
      if ( XmlPropertyFlag )
      {
         Stage = h_g::CloneStage(Nodes[i]->GetPropertyUpper("TYPE").c_str());
         ControlMap[Name] = Stage;
         Stage->SetGroupId(GroupId);
         Stage->SetName(Name);
         Stage->LoadProperty(Nodes[i], XmlPropertyFlag);
         Stage->CreateIcon(this);
         Stage->SetColor();
         TmpStr = Nodes[i]->GetProperty("X").c_str();
         x = TmpStr.ToIntDef(0);
         TmpStr = Nodes[i]->GetProperty("Y").c_str();
         y = TmpStr.ToIntDef(0);
         Stage->Move(x, y);
      }
      else
      {
         Stage = h_g::CloneStage(Nodes[i]->GetValueUpper("TYPE").c_str());
         ControlMap[Name] = Stage;
         Stage->SetGroupId(GroupId);
         Stage->SetName(Name);
         Stage->LoadProperty(Nodes[i], XmlPropertyFlag);
         Stage->CreateIcon(this);
         Stage->SetColor();
         TmpStr = Nodes[i]->GetValue("X").c_str();
         x = TmpStr.ToIntDef(0);
         TmpStr = Nodes[i]->GetValue("Y").c_str();
         y = TmpStr.ToIntDef(0);
         Stage->Move(x, y);
      }
   }

   XmlTree->GetChildren("LINK", Nodes);

   for( int i = 0; i < Nodes.size(); i++ )
   {
      UTF8String TmpStr;
      HLinkInfo LinkInfo;
      LinkInfo.Name = NewLinkName();
      if ( XmlPropertyFlag )
      {
         LinkInfo.StartControl = Nodes[i]->GetPropertyUpper("START_JOB").c_str();
         LinkInfo.EndControl = Nodes[i]->GetPropertyUpper("END_JOB").c_str();
      }
      else
      {
         LinkInfo.StartControl = Nodes[i]->GetValueUpper("START_JOB").c_str();
         LinkInfo.EndControl = Nodes[i]->GetValueUpper("END_JOB").c_str();
      }
      if ( ControlMap.find(LinkInfo.StartControl) == ControlMap.end() ||
           ControlMap.find(LinkInfo.EndControl) == ControlMap.end() )
      {
         continue;
      }
      LinkMap[LinkInfo.Name] = LinkInfo;
      HStage *StartControl = ControlMap[LinkInfo.StartControl];
      HStage *EndControl = ControlMap[LinkInfo.EndControl];
      StartControl->AddToSuccJobSet(EndControl->GetGroupId() +
         h_g::JobNameDelimiter + LinkInfo.EndControl);
      if ( StartControl->GetType() != "EXTERN_JOB" )
      {
         EndControl->IncInDegreeWithinGroup();
      }
   }
}

void __fastcall HDesignControl::RefreshFromXmlTree(HXmlTree *XmlTree,
   bool XmlPropertyFlag, UTF8String &ErrorJobName)
{
   vector<HXmlTree*> Nodes;

   XmlTree->GetChildren("JOB", Nodes);

   for( int i = 0; i < Nodes.size(); i++ )
   {
      UTF8String Name;
      UTF8String TmpStr;
      HStage *Stage;
      int x, y;
      if ( XmlPropertyFlag )
      {
         Name = Nodes[i]->GetPropertyUpper("NAME").c_str();
      }
      else
      {
         Name = Nodes[i]->GetValueUpper("NAME").c_str();
      }
      if ( ControlMap.find(Name) == ControlMap.end() )
      {
         continue;
      }
      Stage = ControlMap[Name];
      UTF8String OldStatus = Stage->GetStatus();
      Stage->SetName(Name);
      Stage->RefreshProperty(Nodes[i], XmlPropertyFlag);
      Stage->SetColor();
      Stage->GetIcon()->Hint = Stage->GetHint();
      UTF8String NewStatus = Stage->GetStatus();
      if( ( NewStatus == "FAIL" || NewStatus == "UNKNOWN" ) &&
          NewStatus != OldStatus )
         ErrorJobName = Name;
   }
}

void __fastcall HDesignControl::RefreshCaption()
{
   for( map<UTF8String, HStage*>::iterator Iter = ControlMap.begin();
        Iter != ControlMap.end(); ++Iter )
      Iter->second->RefreshCaption();
}

void __fastcall HDesignControl::SaveToJobList(map<UTF8String, HJobListInfo> &JobMap,
   bool CriticalFlag)
{
   for( map<UTF8String, HStage*>::iterator Iter = ControlMap.begin();
        Iter != ControlMap.end(); ++Iter )
   {
      HStage *Stage = Iter->second;
      UTF8String Type = Stage->GetType();
      if ( !CriticalFlag && Type != "JOB" && Type != "EVENT_FIRE" &&
           Type != "EVENT_WAIT" && Type != "TIME" && Type != "BATCH" )
      {
         continue;
      }
      HJobListInfo Info;
      Stage->GetJobListInfo(Info);
      JobMap[Info.Name] = Info;
   }
}

void __fastcall HDesignControl::SaveToPartTimeList(vector<HPartTimeInfo> &PartVec)
{
   for( map<UTF8String, HStage*>::iterator Iter = ControlMap.begin();
        Iter != ControlMap.end(); ++Iter )
   {
      HStage *Stage = Iter->second;
      UTF8String Type = Stage->GetType();
      if ( Type != "JOB" && Type != "EVENT_FIRE" &&
           Type != "EVENT_WAIT" && Type != "TIME" && Type != "BATCH" )
      {
         continue;
      }
      Stage->GetPartTimeInfo(PartVec);
   }
}

void __fastcall HDesignControl::SaveToGanttList(const TDateTime &StartTime,
   const TDateTime &EndTime, bool PartitionFlag, int Time, vector<HGanttInfo> &Vec)
{
   for( map<UTF8String, HStage*>::iterator Iter = ControlMap.begin();
        Iter != ControlMap.end(); ++Iter )
   {
      HStage *Stage = Iter->second;
      UTF8String Type = Stage->GetType();
      if ( Type != "JOB" && Type != "BATCH" )
      {
         continue;
      }
      HGanttInfo Info;
      if ( Stage->GetGanttInfo(StartTime, EndTime, PartitionFlag, Time, Info) )
      {
         Vec.push_back(Info);
      }
   }
}

void __fastcall HDesignControl::ReloadUpperGroupMap(const UTF8String &Name,
   map<UTF8String, UTF8String> &UpperGroupMap)
{
   for( map<UTF8String, HStage*>::iterator Iter = ControlMap.begin();
        Iter != ControlMap.end(); Iter++ )
   {
      HStage *Stage = Iter->second;
      if ( Stage->GetType() == "GROUP" )
      {
         HJobListInfo Info;
         Stage->GetJobListInfo(Info);
         UpperGroupMap[Info.Group] = Name;
      }
   }
}

void __fastcall HDesignControl::RefreshBatchColor(int ServerIdx)
{
   for ( map<UTF8String, HStage*>::iterator Iter = ControlMap.begin();
         Iter != ControlMap.end(); Iter++ )
   {
      HStageBatch *Batch = dynamic_cast<HStageBatch*>(Iter->second);
      if ( Batch != NULL && Batch->MatchServerIdx(ServerIdx) )
      {
         Batch->SetColor();
      }
   }
}

#pragma package(smart_init)
